#ifndef _CCGIS_ITERATOR_H_
#define _CCGIS_ITERATOR_H_

#include "afxtempl.h"

namespace ccgis{

template <class Item>
class CIterator
{
public:
	virtual void First() = 0;
	virtual void Next() = 0;
	virtual BOOL IsDone() const = 0;
	virtual Item CurrentItem() const = 0;
protected:
	CIterator(){}
};


template <class Item>
class CArrayIterator : public CIterator<Item>
{
public:
	CArrayIterator(const CArray<Item, Item>* aList) : m_aList(aList), m_nCurrent(0){}
	virtual void First(){	m_nCurrent = 0;		}
	virtual void Next(){	m_nCurrent ++;	}
	virtual BOOL IsDone() const	{	return m_nCurrent >= m_aList->GetSize();	}
	virtual Item CurrentItem() const	{	return (*m_aList)[m_nCurrent];	}
private:
	const CArray<Item, Item>* m_aList;
	long m_nCurrent;
};


template <class Item>
class CIteratorPtr
{
public:
	CIteratorPtr(CIterator<Item>* i) : m_pIterator(i) {}
	~CIteratorPtr() { delete m_pIterator; }

	CIterator<Item>* operator->() { return m_pIterator; }
	CIterator<Item>& operator*() { return *m_pIterator; }

	void First() {		m_pIterator->First(); }
	void Next() {	m_pIterator->Next(); }
	BOOL IsDone() {		return m_pIterator->IsDone(); }
	Item CurrentItem() {	return m_pIterator->CurrentItem(); }

private:
	//disallow copy and assignment to avoid
	//multiple deletions of m_pIterator

	CIteratorPtr(const CIteratorPtr&);
	CIteratorPtr& operator=(const CIteratorPtr&);

private:
	CIterator<Item>* m_pIterator;
};

}

#endif//_CCGIS_ITERATOR_H_